// 引入ajax请求接口函数
import {
  reqRegister,
  reqLogin,
  reqUpdate,
  reqUser,
  reqUserList,
  reqChatMsg,
  reqReadMsg,
} from '../api/index'
// 引入type
import {
  AUTH_SUCCESS,
  ERROR_MSG,
  RECEIVE_USER,
  RESET_USER,
  RECEIVE_USER_LIST,
  RECEIVE_MSG_LIST,
  RECEIVE_MSG,
  READ_MSG,
} from './actionTypes'
import { socket } from '../utils/socket' // 引入socket连接对象  可以emit()
// action创建函数 返回一个对象 包含type 和 要更新的数据  该函数用来更新store中的 state状态 ，这个函数由dispatch来分发
// 定义授权成功的同步action  该函数执行返回一个对象  type  和 要改变的数据
const authSuccess = (data) => ({type: AUTH_SUCCESS, data})
// 定义错误信息的同步action  该函数执行返回一个对象  type  和 要改变的数据
const errorMsg = (data) => ({type: ERROR_MSG, data})
const receiveUser = (data) => ({type: RECEIVE_USER, data}) // 同步更新用户的actions
export const resetUser = data => ({type: RESET_USER, data}) // 同步重置用户信息的action
const receiveUserList = list => ({type: RECEIVE_USER_LIST, list})  // 同步设置userliat的action
const receiveMsgList = data => ({type: RECEIVE_MSG_LIST, data}) // 同步改变chat的action
const receiveOneMsg = data => ({type: RECEIVE_MSG, data}) // 添加一个消息的 同步action
const msgRead = data => ({type: READ_MSG, data})

// 分发action异步的函数
// 异步获取用户聊天相关信息的action  用户登录 注册 获取用户信息 这些操作成功时候都需要获取聊天消息 使用的时候传入dispatch函数
async function getChatMsg (dispatch) {
  // 验证isOnGetMsg，保证只注册一次监听事件， 不能重复注册事件
  if (!socket.isOnGetMsg) {
    // 初始化socket.io 注册监听事件 监听服务器发送的消息  传入回调函数  接收消息就会执行回调函数
    socket.initOnGetMsg(data => {
      console.log(data)
      // 将dispatch函数传入 socket就可以在触发 getMsg事件回调的时候调用更新store中的chat
      dispatch(receiveOneMsg(data))
    })
  }
  // 发送ajax请求请求服务器端的聊天相关信息
  const res = await reqChatMsg()
  const result = res.data
  if (result.code === 0) {
    //  成功 分发同步action 改变state  返回值是一个对象：结构{ users:{}, chatMsg:[] }
    // console.log(result)
    dispatch(receiveMsgList(result.data)) // 改变store中的 chat的状态
  }
}

// 注册接口分发actions  参数需要一个对象 包含用户名密码
export const register = (user) => {
  // 密码 合法性验证
  let {username, password, confirmPassword} = user
  // console.log(user)
  if (password !== confirmPassword) {
    // 两次密码不一致那么直接返回一个同步的action 改变store的msg错误信息
    return errorMsg({msg: '两次密码不一致~'})
  }
  // thunk中间件的异步action分发dispatch的写法 返回一个h函数 参数是dispath 和getstate 调用的组件会自动执行返回的dispatch
  return async (dispatch, getState) => {
    // 发送ajax得到一个promise对象，await语法同步返回一个 异步的结果的返回值
    let res = await reqRegister(user)
    // 返回值是一个对象：格式{    code: 0, type,msg: '注册成功', username,header: ''}
    let result = res.data
    console.log(result)
    // dispatch分发分发的参数需要是一个对象
    if (!result.code) {
      getChatMsg(dispatch) // 登录成功就获取聊天相关消息 并改变分发dispatch改变 state
      //  code 为0 表示注册成功 异步结束后同步执行一个dispatch() reducer根据action的type改变store中state的状态
      dispatch(authSuccess(result))
      
    } else {
      //  注册失败
      dispatch(errorMsg(result))
    }
  }
}

// 登录接口  参数需要一个对象 包含用户名密码
export const login = (user) => {
  console.log(user)
  // 返回一个dispatch
  return async dispatch => {
    // 发送ajax await语法同步返回一个 异步的结果
    let res = await reqLogin(user)
    let result = res.data
    // 返回值是一个对象：格式{    code: 0, type,msg: '登录成功', username, header: ''}
    console.log(result)
    if (!result.code) {
      //  code 为0 表示登录成功 异步结束后同步执行一个dispatch() 改变store中state的状态
      getChatMsg(dispatch)
      dispatch(authSuccess(result))
      
    } else {
      //  登录失败
      dispatch(errorMsg(result))
    }
  }
}

// 更新信息接口  参数需要一个对象
export const update = (user) => {
  console.log(user)
  // 返回一个dispatch
  return async dispatch => {
    // 发送ajax await语法同步返回一个 异步的结果
    let res = await reqUpdate(user)
    let result = res.data
    // 返回值是一个对象：格式{    code: 0, type,msg: '', username, header: ''}
    console.log(result)
    if (!result.code) {
      // code==0 成功
      dispatch(receiveUser(result))
    } else {
      //  更新失败
      dispatch(resetUser(result))
    }
  }
}

// 获取用户信息的接口 不需要参数
export const getUser = () => {
  return async dispatch => {
    let res = await reqUser()
    let result = res.data
    // console.log(result)
    if (result.code === 0) {
      // 成功
      getChatMsg(dispatch)
      dispatch(receiveUser(result))
      
    } else {
      // 失败
      dispatch(resetUser(result))
    }
  }
}

// 获取userlist的  异步action
export const getUserList = (type) => {
  return async dispatch => {
    const res = await reqUserList(type)
    const result = res.data
    // console.log(result)
    //  对响应的code进行判断 成功失败
    if (result.code === 0) {
      // 成功 分发一个设置userliat的同步acion
      dispatch(receiveUserList(result.list))
    } else {
      //  失败
      //   dispatch(resetUser({}))
    }
  }
}

// 用户发送聊天消息的action
export const sendMsg = data => {
  return dispatch => {
    // console.log(data)
    // 向服务器发送消息
    socket.emit('sendMsg', data)
  }
  
}

// 更新已读消息的异步action
export const readMsg = ({from, to}) => {
  // console.log(from)
  return async dispatch => {
    //  发送ajax
    let res = await reqReadMsg(from)
    let result = res.data
    console.log(result)
    if (result.code === 0) {
      let count = result.count
      //  分发同步acion
      dispatch(msgRead({from, to, count}))
    }
  }
  
}